<i18n lang="json">
{
  "zh-cn": {
    "intro": "忘记密码了? 🔒",
    "login": "去登录",
    "passwordSuccess":"恭喜您修改密码成功!",
    "successCode":"发送验证码成功!",
    "form": {
      "account": "手机号",
      "captcha": "验证码",
      "sendCaptcha": "发送验证码",
      "password": "新密码",
      "imgCaptcha":"图形验证码",
      "confirm": "确认",
      "captchaCountdown": "{0} 秒后可重新发送"
    },
    "rules": {
      "account": "请输入手机号",
      "phone": "手机号格式错误",
      "captcha": "请输入验证码",
      "password": "请输入新密码",
      "passwordLength": "密码长度为6到18位",
      "code": "请输入图形验证码"
    }
  },
  "en": {
    "intro": "Forget password? 🔒",
    "login": "Go to login",
    "passwordSuccess":"Reset Password Success!",
    "successCode":"Successfully sent verification code",
    "form": {
      "account": "Account",
      "captcha": "Captcha",
      "sendCaptcha": "Send Captcha",
      "password": "New Password",
      "checkPassword": "Check Password",
      "imgCaptcha":"Graphic verification code",
      "confirm": "Confirm",
      "captchaCountdown": "Can resend in {0}s"
    },
    "rules": {
      "account": "Please enter an account",
      "captcha": "Please enter a captcha",
      "phone": "Phone number format error",
      "password": "Please enter a password",
      "passwordLength": "Password length is 6 to 18 bits",
      "checkPassword": "Please enter the password again",
      "code": "Please enter a verification code"
    }
  }
}
</i18n>

<script setup lang="ts">
import apiUser from '@/api/modules/user'
import { FormControl, FormField, FormItem, FormMessage } from '@/ui/shadcn/ui/form'
import { toTypedSchema } from '@vee-validate/zod'
import { useForm } from 'vee-validate'
import { useI18n } from 'vue-i18n'
import { toast } from 'vue-sonner'
import * as z from 'zod'

defineOptions({
  name: 'RegisterForm',
})

const emits = defineEmits<{
  onLogin: [account?: string]
  onResetPassword: [account?: string]
}>()

const { t } = useI18n()

const loading = ref(false)
const form = useForm({
  validationSchema: toTypedSchema(
    z.object({
      username: z.string().min(1, t('rules.account')).regex(/^\d{11}$/, t('rules.phone')),
      smsCode: z.string().min(4, t('rules.captcha')),
      password: z.string().min(1, t('rules.password')).min(6, t('rules.passwordLength')).max(18, t('rules.passwordLength')),
      code: z.string().min(1, t('rules.code')),
    }),
  ),
  initialValues: {
    username: '',
    smsCode: '',
    password: '',
    code: '',
  },
})
const imgCaptcha = ref<string>('')
const uuid = ref<string>('')
// 获取图形验证码
async function getImgCaptcha() {
  apiUser.captchaImage().then((res: any) => {
    if (res.code === 200) {
      uuid.value = res.data.uuid
      refreshCaptcha(res.data.img)
    }
  })
}
// 获取验证码逻辑
async function refreshCaptcha(url: string) {
  try {
    imgCaptcha.value = `data:image/png;base64,${url}`
  }
  catch (error) {
    toast.error(t('codeTextError'))
  }
}

const onSubmit = form.handleSubmit((values) => {
  loading.value = true
  const onResetData: any = {
    phone: values.username,
    password: values.password,
    smsCode: values.smsCode,
  }
  apiUser.forgetPwd(onResetData).then((res: any) => {
    if (res.code === 200) {
      toast.success(t('passwordSuccess'))
      emits('onResetPassword', values.username)
    }
    else {
      loading.value = false
    }
  })
})

const countdown = ref(0)
const countdownInterval = ref(Number.NaN)
async function handleSendCaptcha(e: any) {
  e.preventDefault()
  e.stopPropagation()
  // 仅验证 username 和 code 字段
  const usernameValidation = await form.validateField('username')
  const codeValidation = await form.validateField('code')
  if (!usernameValidation.valid) {
    return
  }
  if (!codeValidation.valid) {
    return
  }
  // // 仅验证 username 和 code 字段
  const phone = form.values.username
  const captcha = form.values.code
  const SmsData = {
    phone: phone as string, // 类型断言
    uuid: uuid.value,
    captcha: captcha as string, // 类型断言
  }
  const res: any = await apiUser.sendForgetPwdSms(SmsData)
  if (res.code === 200) {
    toast.success(t('successCode'))
    countdown.value = 60
    countdownInterval.value = window.setInterval(() => {
      countdown.value--
      if (countdown.value === 0) {
        clearInterval(countdownInterval.value)
      }
    }, 1000)
  }
  else if (res.code === 201) {
    toast.error(res.msg)
  }
  else {
    await getImgCaptcha()
  }
}

onMounted(() => {
  getImgCaptcha()
})
</script>

<template>
  <div class="min-h-500px w-full flex-col-stretch-center p-12">
    <form @submit.prevent="onSubmit">
      <FaBlurReveal :delay="0.2" :duration="0.4" class="mb-8 space-y-2">
        <h3 class="text-4xl color-[var(--el-text-color-primary)] font-bold">
          {{ t('intro') }}
        </h3>
      </FaBlurReveal>
      <FormField v-slot="{ componentField, errors }" name="username">
        <FormItem class="relative pb-6 space-y-0">
          <FormControl>
            <FaInput type="text" :placeholder="t('form.account')" class="w-full" :class="errors.length && 'border-destructive'" v-bind="componentField" />
          </FormControl>
          <Transition enter-active-class="transition-opacity" enter-from-class="opacity-0" leave-active-class="transition-opacity" leave-to-class="opacity-0">
            <FormMessage class="absolute bottom-1 text-xs" />
          </Transition>
        </FormItem>
      </FormField>
      <FormField v-slot="{ componentField, value, errors }" name="password">
        <FormItem class="relative pb-6 space-y-0">
          <FormControl>
            <FaInput type="password" :placeholder="t('form.password')" class="w-full" :class="errors.length && 'border-destructive'" v-bind="componentField" />
          </FormControl>
          <FormDescription>
            <FaPasswordStrength :password="value" class="mt-2" />
          </FormDescription>
          <Transition enter-active-class="transition-opacity" enter-from-class="opacity-0" leave-active-class="transition-opacity" leave-to-class="opacity-0">
            <FormMessage class="absolute bottom-1 text-xs" />
          </Transition>
        </FormItem>
      </FormField>
      <div class="flex-start-between gap-2">
        <FormField v-slot="{ componentField, errors }" name="code">
          <FormItem class="relative pb-6 space-y-0">
            <FormControl>
              <FaInput type="text" :placeholder="t('form.imgCaptcha')" class="w-full" :class="errors.length && 'border-destructive'" v-bind="componentField" />
            </FormControl>
            <Transition enter-active-class="transition-opacity" enter-from-class="opacity-0" leave-active-class="transition-opacity" leave-to-class="opacity-0">
              <FormMessage class="absolute bottom-1 text-xs" />
            </Transition>
          </FormItem>
        </FormField>
        <div class="flex-1">
          <img :src="imgCaptcha" alt="imgCaptcha" class="w-img" @click="getImgCaptcha">
        </div>
      </div>
      <div class="flex-start-between gap-2">
        <FormField v-slot="{ componentField, value, setValue }" name="smsCode">
          <FormItem class="relative pb-6 space-y-0">
            <FormControl>
              <FaPinInput :model-value="value" :name="componentField.name" :length="4" class="border-destructive" @update:model-value="val => setValue(val)" />
            </FormControl>
            <Transition enter-active-class="transition-opacity" enter-from-class="opacity-0" leave-active-class="transition-opacity" leave-to-class="opacity-0">
              <FormMessage class="absolute bottom-1 text-xs" />
            </Transition>
          </FormItem>
        </FormField>
        <FaButton variant="outline" size="lg" :disabled="countdown > 0" class="flex-1 px-4" @click.stop="handleSendCaptcha">
          {{ countdown === 0 ? t('form.sendCaptcha') : t('form.captchaCountdown', [countdown]) }}
        </FaButton>
      </div>
      <FaButton :loading="loading" size="lg" class="mt-4 w-full" type="submit">
        {{ t('form.confirm') }}
      </FaButton>
      <div class="mt-4 flex-center gap-2 text-sm color-[var(--el-text-color-secondary)]">
        <FaButton variant="link" class="h-auto p-0" @click="emits('onLogin', form.values.username)">
          {{ t('login') }}
        </FaButton>
      </div>
    </form>
  </div>
</template>

<style scoped lang="scss">
.w-img{
  width: 100%;
  height: 40px;
}
</style>
